<template>
    <div class="app-container">
        <!-- 记录标题 -->
        <div class="operation-container">
            <span style="width: 130px;font-size: 1em">记录主题:</span>
            <el-input style="height: 1.8rem" v-model="recordForm.title" placeholder="请输入记录标题"></el-input>
            <el-button type="danger" style="margin: 0 30px 0" @click="openModel">发布记录</el-button>
        </div>
        <el-row :gutter="10" align="middle" style="margin-top: 10px;">
            <el-col :span="1.5">
                <!-- 图片上传 -->
                <el-upload accept="image/*" multiple action="/api/admin/recordImage/upload"
                           :show-file-list="false" :headers="authorization"
                           :before-upload="beforeUpload" :on-success="handleISuccess">
                    点击进行图片上传
                    <svg-icon icon-class="album" size="1.5rem" color="#838383"
                              style="padding-top:0.1rem;"></svg-icon>
                </el-upload>
            </el-col>
            <el-col :span="1.5" style="margin-left: 30px">
                <!-- 视频上传 -->
                <el-upload accept="video/*" multiple action="/api/admin/recordVideo/upload"
                           :show-file-list="false" :headers="authorization"
                           :before-upload="beforeUpload" :on-success="handleVSuccess">
                    点击进行视频上传
                    <svg-icon icon-class="color" size="1.5rem" color="#838383"
                              style="padding-top:0.1rem;"></svg-icon>
                </el-upload>
            </el-col>
        </el-row>
        <!-- 图片上传 -->
        <el-upload accept="image/*" v-show="uploadList.length > 0 && updateType === 1"
                   action="/api/admin/recordImage/upload"
                   :headers="authorization" list-type="picture-card" :file-list="uploadList" multiple
                   :before-upload="beforeUpload" :on-success="handleISuccess" :on-remove="handleRemove"
                   :on-preview="handlePictureCardPreview" style="margin-top:1rem;">
            <el-icon>
                <Plus/>
            </el-icon>
        </el-upload>
        <!-- 图片预览 -->
        <el-dialog v-model="dialogVisible" append-to-body>
            <img :src="dialogImageUrl" style="max-width:100%" alt="图片"/>
        </el-dialog>
        <!-- 视频预览 -->
        <video v-show="updateType === 2" :src="dialogVideoUrl" controls class="video-box"/>
        <!-- 发布或修改对话框 -->
        <el-dialog title="发布记录" v-model="addOrUpdate" width="600px" top="0.5vh" append-to-body center draggable>
            <el-form ref="recordFormRef" label-width="80px" :model="recordForm" :rules="rules">
                <!-- 记录类型 -->
                <el-form-item label="记录类别" prop="type">
                    <el-select v-model="recordForm.type" placeholder="请选择类别">
                        <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value">
                        </el-option>
                    </el-select>
                </el-form-item>
                <!-- 记录内容 -->
                <el-form-item label="题目内容" prop="content">
                    <el-input v-model="recordForm.content" :rows="3" type="textarea" placeholder="请输入记录内容"/>
                </el-form-item>
                <!-- 记录标签 -->
                <el-form-item label="记录标签" prop="tagNameList">
                    <el-tag v-for="(item, index) of recordForm.tagNameList" :key="index" :disable-transitions="true"
                            :closable="true" @close="removeTag(item)" style="margin-right: 1rem;">
                        {{ item }}
                    </el-tag>
                    <!-- 标签选项 -->
                    <el-popover placement="bottom-start" :offset="20" width="420" trigger="click"
                                v-if="recordForm.tagNameList.length < 3"
                                :popper-style="popoverStyle">
                        <template #reference>
                            <el-button type="success" plain icon="Plus">添加</el-button>
                        </template>
                        <div class="popover-title">标签</div>
                        <!-- 搜索框 -->
                        <el-autocomplete style="width: 100%" v-model="tagName" :fetch-suggestions="searchTag"
                                         placeholder="请输入标签名搜索,enter可添加自定义标签" :trigger-on-focus="false"
                                         @keyup.enter="saveTag"
                                         @select="handleSelectTag">
                            <template #default="{ item }">
                                <div>{{ item.tagName }}</div>
                            </template>
                        </el-autocomplete>
                        <!-- 标签 -->
                        <div class="popover-container">
                            <div style="margin-bottom: 1rem">点击标签进行添加</div>
                            <el-tag v-for="(item, index) of tagList" :key="index" :class="tagClass(item.tagName)"
                                    @click="addTag(item.tagName)" style="margin-right: 1rem;">
                                {{ item.tagName }}
                            </el-tag>
                        </div>
                    </el-popover>
                </el-form-item>
                <!-- 缩略图 -->
                <el-form-item label="缩略图" prop="cover">
                    <el-upload drag :show-file-list="false" :headers="authorization"
                               action="/api/admin/recordImage/upload"
                               accept="image/*" :before-upload="beforeUpload" :on-success="handleCSuccess">
                        <el-icon class="el-icon--upload" v-if="recordForm.cover === ''">
                            <upload-filled/>
                        </el-icon>
                        <div class="el-upload__text" v-if="recordForm.cover === ''">
                            将文件拖到此处，或<em>点击上传</em>
                        </div>
                        <img v-else :src="recordForm.cover" width="360" alt="缩略图"/>
                    </el-upload>
                </el-form-item>
                <!-- 置顶 -->
                <el-form-item label="置顶" prop="isTop">
                    <el-switch v-model="recordForm.isTop" :active-value="1" :inactive-value="0"></el-switch>
                </el-form-item>
                <!-- 推荐 -->
                <el-form-item label="推荐" prop="isRecommend">
                    <el-switch v-model="recordForm.isRecommend" :active-value="1" :inactive-value="0"></el-switch>
                </el-form-item>
                <!-- 发布形式 -->
                <el-form-item label="发布形式" prop="status">
                    <el-radio-group v-model="recordForm.status">
                        <el-radio :label="1">公开</el-radio>
                        <el-radio :label="2">私密</el-radio>
                        <el-radio :label="3">草稿</el-radio>
                    </el-radio-group>
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button v-if="recordForm.status != 3" type="success" @click="submitForm">发布记录</el-button>
                    <el-button v-else type="success" @click="submitForm">保存草稿</el-button>
                    <el-button @click="addOrUpdate = false">取 消</el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<script setup lang="ts">
import {addRecord, editRecord, getTagOption, updateRecord} from "@/api/record";
import {RecordForm, TagVO} from "@/api/record/types";
import router from "@/router";
import useStore from "@/store";
import {notifySuccess} from "@/utils/modal";
import {getToken, token_prefix} from '@/utils/token';
import {useDateFormat} from '@vueuse/core';
import {AxiosResponse} from 'axios';
import {ElMessage, FormInstance, FormRules, UploadFile, UploadRawFile} from 'element-plus';
import * as imageConversion from 'image-conversion';
import {computed, onMounted, reactive, ref, toRefs} from "vue";
import {useRoute} from "vue-router";
import {Picture} from "@/model";

const route = useRoute();
const recordId = route.params.recordId;
const recordFormRef = ref<FormInstance>();
const title = ref(useDateFormat(new Date(), "YYYY-MM-DD"));
const {tag} = useStore();
const dialogImageUrl = ref('');
const dialogVideoUrl = ref('');
const dialogVisible = ref(false);
const rules = reactive<FormRules>({
    tagNameList: [{required: true, message: "记录标签不能为空", trigger: "blur"}],
});
const authorization = computed(() => {
    return {
        Authorization: token_prefix + getToken(),
    }
});
const tagClass = computed(() => {
    return function (item: string) {
        const index = recordForm.value.tagNameList.indexOf(item);
        return index !== -1 ? "tag-item-select" : "tag-item";
    };
});
const data = reactive({
    addOrUpdate: false,
    updateType: 0,
    typeList: [
        {
            value: 1,
            label: "约会",
        },
        {
            value: 2,
            label: "活动",
        },
        {
            value: 3,
            label: "赛事",
        },
        {
            value: 4,
            label: "帮助",
        }
    ],
    recordForm: {
        id: undefined,
        userId: 1,
        cover: "",
        title: title.value,
        content: "",
        tagNameList: [],
        type: 1,
        isTop: 0,
        isRecommend: 0,
        status: 1,
        images: undefined,
        video: undefined
    } as RecordForm,
    tagList: [] as TagVO[],
    tagName: "",
    uploadList: [] as Picture[],
    popoverStyle: {
        backgroundColor: '#e8eaf1',
        color: '#333',
        boxShadow: '0 0 10px rgba(0, 0, 0, 0.5)'
    }
});
const {addOrUpdate, updateType, typeList, recordForm, tagList, tagName, uploadList, popoverStyle} = toRefs(data);

const openModel = () => {
    if (recordForm.value.title.trim() == "") {
        ElMessage.error("记录标题不能为空");
        return false;
    }
    recordFormRef.value?.clearValidate();
    getTagOption().then(({data}) => {
        tagList.value = data.data;
    });
    addOrUpdate.value = true;
};
// 操作标签 start
const removeTag = (item: string) => {
    const index = recordForm.value.tagNameList.indexOf(item);
    recordForm.value.tagNameList.splice(index, 1);
};
const handleSelectTag = (item: TagVO) => {
    addTag(item.tagName);
};
const saveTag = () => {
    if (tagName.value.trim() != "") {
        addTag(tagName.value);
        tagName.value = "";
    }
};
const addTag = (item: string) => {
    if (recordForm.value.tagNameList.indexOf(item) == -1) {
        recordForm.value.tagNameList.push(item);
    }
};
const searchTag = (keyword: string, cb: (arg: TagVO[]) => void) => {
    const results = keyword
        ? tagList.value.filter(createTagFilter(keyword))
        : tagList.value
    cb(results);
};

const createTagFilter = (queryString: string) => {
    return (restaurant: TagVO) => {
        return (
            restaurant.tagName.indexOf(queryString) !== -1
        )
    }
};
// 操作标签 end
// 取消
const cancel = () => {
    addOrUpdate.value = false;
    recordFormRef.value?.clearValidate();
    reset();
};
// 重置表单
const reset = () => {
    recordForm.value = {
        id: undefined,
        userId: 1,
        cover: "",
        title: title.value,
        content: "",
        tagNameList: [],
        type: 1,
        isTop: 0,
        isRecommend: 0,
        status: 1,
        images: undefined,
        video: undefined
    };
    updateType.value = 0;
    uploadList.value = [];
};
const handleCSuccess = (response: AxiosResponse) => {
    recordForm.value.cover = response.data;
};
const handleISuccess = (response: AxiosResponse) => {
    uploadList.value.push({url: response.data});
    updateType.value = 1;
};
const handleRemove = (file: UploadFile) => {
    uploadList.value.forEach((item, index) => {
        if (item.url == file.url) {
            uploadList.value.splice(index, 1);
        }
    });
    if (uploadList.value.length === 0) {
        updateType.value = 0;
    }
};
const handlePictureCardPreview = (file: UploadFile) => {
    dialogImageUrl.value = file.url!;
    dialogVisible.value = true;
};
const handleVSuccess = (response: AxiosResponse) => {
    console.log("url=", response.data);
    dialogVideoUrl.value = response.data;
    updateType.value = 2;
};
const beforeUpload = (rawFile: UploadRawFile) => {
    return new Promise(resolve => {
        if (rawFile.type.startsWith('image/')) {
            // 二选一
            dialogVideoUrl.value = '';
            // 对图片进行压缩
            if (rawFile.size / 1024 < 200) {
                resolve(rawFile);
            }
            imageConversion
                .compressAccurately(rawFile, 200)
                .then(res => {
                    resolve(res);
                });
        } else if (rawFile.type.startsWith('video/')) {
            // 二选一
            uploadList.value = [];
            // 对视频进行压缩
            if (rawFile.size / 1024 < 1024 * 10) {
                // 如果视频大小小于 10MB，则直接返回原始文件
                resolve(rawFile);
            } else {
                // 如果视频大小大于 10MB,暂时不操作
                resolve(rawFile);
            }
        }
    });
};
const submitForm = () => {
    recordFormRef.value?.validate((valid) => {
        if (valid) {
            // 转换图片
            if (uploadList.value.length > 0) {
                let imgList: string[] = [];
                uploadList.value.forEach((item) => {
                    imgList.push(item.url);
                });
                recordForm.value.images = JSON.stringify(imgList);
            } else {
                recordForm.value.images = "";
            }
            // 绑定视频url
            if (dialogVideoUrl.value) {
                recordForm.value.video = dialogVideoUrl.value
            } else {
                recordForm.value.video = "";
            }
            if (recordForm.value.id !== undefined) {
                updateRecord(recordForm.value).then(({data}) => {
                    if (data.flag) {
                        notifySuccess(data.msg);
                        tag.delView({path: `/record/writer/${recordForm.value.id}`});
                        router.push({path: "/record/list"});
                    }
                    cancel()
                });
            } else {
                addRecord(recordForm.value).then(({data}) => {
                    if (data.flag) {
                        notifySuccess(data.msg);
                        tag.delView({path: "/record/write"});
                        router.push({path: "/record/list"});
                        cancel();
                    }
                });
            }
        }
    })
};
onMounted(() => {
    if (recordId) {
        editRecord(Number(recordId)).then(({data}) => {
            if (data.flag) {
                recordForm.value = data.data;
                if (data.data.imgList) {
                    data.data.imgList.forEach((item) => {
                        uploadList.value.push({url: item});
                    });
                    updateType.value = 1;
                } else if (data.data.video) {
                    dialogVideoUrl.value = data.data.video;
                    updateType.value = 2;
                }
            } else {
                tag.delView({path: `/record/writer/${recordId}`});
                router.push({path: "/record/list"});
            }
        });
    }
    getTagOption().then(({data}) => {
        tagList.value = data.data;
    });
});
</script>

<style scoped>
.operation-container {
    display: flex;
    align-items: center;
    margin-bottom: 1.25rem;
}

.popover-title {
    margin-bottom: 1rem;
    text-align: center;
}

.popover-container {
    margin-top: 1rem;
    height: 260px;
    overflow-y: auto;
}

.video-box {
    width: 60%;
    margin: 10px 30px 30px;
    border-radius: 10px;
    box-shadow: 0 0 10px 8px rgba(39, 42, 39, 0.6);
}

.tag-item {
    margin-right: 1rem;
    margin-bottom: 1rem;
    cursor: pointer;
}

.tag-item-select {
    margin-right: 1rem;
    margin-bottom: 1rem;
    cursor: not-allowed;
    color: #ccccd8 !important;
}
</style>